package org.wwx.proxy;

import org.wwx.client.RegistryClient;
import org.wwx.common.Invocation;
import org.wwx.loadbalancing.LoadBalancing;
import org.wwx.protocol.HttpClient;
import org.wwx.register.model.ServiceInstance;

import java.lang.reflect.Proxy;
import java.util.List;

/**
 * @date 2025/6/5
 * @author王闻薪
 */
public class ProxyFactory {
    @SuppressWarnings("unchecked")
    public static <T> T getProxy(Class<T> interfaceClass) {
        if (!Object.class.isAssignableFrom(interfaceClass)) {
            throw new IllegalArgumentException("Type parameter T must be a reference type");
        }
        return (T) Proxy.newProxyInstance(interfaceClass.getClassLoader(), new Class[]{interfaceClass}, (proxy, method, args) -> {
            if (method.getDeclaringClass() == Object.class) {
                switch (method.getName()) {
                    case "equals":
                        return proxy == args[0];
                    case "hashCode":
                        return System.identityHashCode(proxy);
                    case "toString":
                        return proxy.getClass().getName() + "@" + Integer.toHexString(System.identityHashCode(proxy));
                }
                throw new UnsupportedOperationException(method.getName());
            }
//            final Invocation invocation = new Invocation(interfaceClass.getName(),
//                    method.getName(), method.getParameterTypes(),
//                    args);
//            final HttpClient httpClient = new HttpClient();
//            final String result = httpClient.send("localhost", 1128, invocation);
//            return result;


            final List<ServiceInstance> instances = RegistryClient.discoverService(interfaceClass.getName());
            if (instances == null || instances.isEmpty()) {
                throw new IllegalStateException("No available service instances for " + interfaceClass.getName());
            }
            ServiceInstance instance = LoadBalancing.random(instances);


            HttpClient client = new HttpClient();
            return client.send(instance.getHost(), instance.getPort(),
                    new Invocation(interfaceClass.getName(), method.getName(), method.getParameterTypes(), args));
        });
    }
}